// // 基础版
// 三个状态：PENDING、FULFILLED、REJECTED
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

function MyPromise(executor) {
  // 初始化state为等待态 
  this.status = PENDING;
  // 存放成功状态的值，默认为 undefined
  this.value = undefined;
  // 存放失败状态的值，默认为 undefined
  this.reason = undefined;
  // 存放成功的回调
  this.onResolvedCallbacks = [];
  // 存放失败的回调
  this.onRejectedCallbacks = [];

  // 这里的resolve和reject不是对象中你的方法
  // 调用此方法就是成功
  let resolve = (value) => {
    // 判断传入元素是否为 Promise 值，如果是，则状态改变必须等待前一个状态改变后再进行改变
    if (value instanceof MyPromise) {
      // 递归解析 
      return value.then(resolve, reject)
    }
    setTimeout(() => {
      // 状态为 PENDING 时才可以更新状态，防止 executor 中调用了两次 resovle/reject 方法
      if (this.status === PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 依次将对应的函数执行
        this.onResolvedCallbacks.forEach(fn => {
          fn(value);
        });
      }
    }, 0);
  }

  // 调用此方法就是失败
  let reject = (reason) => {
    // 保证代码的执行顺序为本轮事件循环的末尾
    setTimeout(() => {
      // 状态为 PENDING 时才可以更新状态，防止 executor 中调用了两次 resovle/reject 方法
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 依次将对应的函数执行
        this.onRejectedCallbacks.forEach(fn => {
          fn(reason);
        });
      }
    }, 0);
  }

  try {
    // 立即执行，将 resolve 和 reject 函数传给使用者  
    executor(resolve, reject);
  } catch (error) {
    reject(error);
  }
}
// 原型方法
MyPromise.prototype.then = function(onFulfilled, onRejected) {
  //解决 onFufilled，onRejected 没有传值的问题
  // 首先判断两个参数是否为函数类型，因为这两个参数是可选参数
  onFulfilled =
    typeof onFulfilled === "function"
      ? onFulfilled
      : function(value) {
        return value;
      };
  //因为错误的值要让后面访问到，所以这里也要跑出个错误，不然会在之后 then 的 resolve 中捕获
  onRejected =
    typeof onRejected === "function"
      ? onRejected
      : function(error) {
        throw error;
      };
  if (this.status === FULFILLED) {
    onFulfilled(this.value);
  }

  if (this.status === REJECTED) {
    onRejected(this.reason);
  }

  if (this.status === PENDING) {
    // 如果promise的状态是 pending，需要将 onFulfilled 和 onRejected 函数存放起来，等待状态确定后，再依次将对应的函数执行
    this.onResolvedCallbacks.push(onFulfilled);

    // 如果promise的状态是 pending，需要将 onFulfilled 和 onRejected 函数存放起来，等待状态确定后，再依次将对应的函数执行
    this.onRejectedCallbacks.push(onRejected);
  }
}

// 测试
const promise = new MyPromise((resolve, reject) => {
  // 传入一个异步操作
  setTimeout(() => {
    resolve('成功');
    console.log('wzy');
  }, 1000);
}).then(
  (data) => {
    console.log('success', data)
  },
  (err) => {
    console.log('faild', err)
  }
)


